﻿using System;
using ETModel;

namespace ETHotfix {
    /// <summary>
    /// 外网消息分发,session读取到消息,根据session关联的(内网或外网)分发器进到Dispatch
    /// </summary>
	public class OuterMessageDispatcher : IMessageDispatcher {
        public void Dispatch(Session session, ushort opcode, object message) {
            DispatchAsync(session, opcode, message).Coroutine();
        }

        public async ETVoid DispatchAsync(Session session, ushort opcode, object message) {
            try {
                switch (message) {
                    case IActorLocationRequest actorLocationRequest: {
                            // gate session收到actor rpc消息，先向actor 发送rpc请求，再将请求结果返回客户端

                            long mapPlayerInstanceId = session.GetComponent<GateClientSessionPlayerComponent>().Player.MapPlayerInstanceId;
                            if (mapPlayerInstanceId == 0) {
                                //todo:这里要输出系统级的通用错误信息
                                ReqError err = new ReqError();
                                return;
                            }
                            var actorMsgSender = Game.Scene.GetComponent<ActorMessageSenderComponent>().Get(mapPlayerInstanceId);

                            int rpcId = actorLocationRequest.RpcId; // 这里要保存客户端的rpcId
                            IResponse response = await actorMsgSender.Call(actorLocationRequest);
                            response.RpcId = rpcId;

                            session.Reply(response);
                            return;
                        }
                    case IActorLocationMessage actorLocationMessage: {
                            //不需要响应的消息,默认是认为发给当前连接对应的MapPlayer
                            long mapPlayerInstanceId = session.GetComponent<GateClientSessionPlayerComponent>().Player.MapPlayerInstanceId;
                            if (mapPlayerInstanceId == 0) {
                                //todo:这里要输出系统级的通用错误信息
                                ReqError err = new ReqError();
                                return;
                            }
                            var actorMsgSender = Game.Scene.GetComponent<ActorMessageSenderComponent>().Get(mapPlayerInstanceId);
                            actorMsgSender.Call(actorLocationMessage).Coroutine();

                            return;
                        }
                }

                Game.Scene.GetComponent<MessageDispatcherComponent>().Handle(session, new MessageInfo(opcode, message));
            } catch (Exception e) {
                Log.Error(e);
            }
        }
    }
}
